package lexer;

import java.io.*;

import tools.BasicTools;

/** 预处理器 */
public class Preprocessor {
    private File file;
    private String code;

    public static void main(String[] args) throws IOException {
        Preprocessor pre = new Preprocessor(args[0]);
        /** input test.c */
        pre.readCode();
        System.out.println("<Pre>读取代码:\n" + pre.getCode());
        /** preprocess */
        pre.preprocess();
        System.out.println("<Pre>预处理结果:\n" + pre.getCode());
        /** output test.i */
        pre.writeCode();
        System.out.println("<Pre>已成功写出预处理后代码.");
    }

    public Preprocessor(String pathName) {
        file = new File(pathName);
    }

    public String getCode() {
        return code;
    }

    public void readCode() throws IOException {
        code = BasicTools.readFromFile(file);
    }

    public void readCode(String code) {
        this.code = code;
    }

    public void preprocess() throws IOException {
        StringReader sr = new StringReader(code.toLowerCase());
        StringBuilder sb = new StringBuilder();
        for (int c1 = sr.read(); c1 != -1; c1 = sr.read()) {
            if (c1 == '/') {
                int c2 = sr.read();
                if (c2 == '/') {
                    // 单行注释
                    for (int c3 = sr.read(); c3 != '\n' && c3 != -1; c3 = sr.read())
                        ;
                    sb.append('\n');
                } else if (c2 == '*') {
                    // 多行注释
                    for (int c4 = 0; c4 != '/' && c4 != -1; c4 = sr.read())
                        for (int c3 = sr.read(); c3 != '*' && c3 != -1; c3 = sr.read())
                            ;
                } else {
                    // 非'//'或'/*', 不是注释
                    sb.append((char) c1);
                    sb.append((char) c2);
                }
            } else {
                // 非'/'开头, 不是注释
                sb.append((char) c1);
            }
        }
        code = sb.toString();
    }

    public void writeCode() throws IOException {
        BasicTools.WriteToFile(BasicTools.replaceFileSuffix(file, ".i"), code);
    }
}
